/*
 * graphstrct.c
 *
 * Provides additional data structures to special views of graphs
 *
 *  Created on: Aug 20, 2011
 *      Author: correa
 */

#include <string.h>
#include "graph.h"

static adjMatrix * 	defaultg = NULL;

int setDefaultGraph( adjMatrix * g) {
	setAdjMatrix(g);
	defaultg = g;
	return 0;
}

// Anti-neighborhoods

int antiNeig(const adjMatrix * g, int r, const int * R, int i, int asz, int * ang, int * surplus_p) {
	if (g) {
		setAdjMatrix(g);
	}

	int ia = 0, j;
	*surplus_p = asz;
	for (j = 0; j < r; j++)
		if (i != j && !hasEdge(R[i], R[j])) {
			(*surplus_p)--;
			if (*surplus_p >= 0)
				ang[ia++] = j;
		}

	if (g && defaultg) {
		setAdjMatrix(defaultg);
	}

	return (*surplus_p < 0) ? GSTERR_NEGATIVE_SURPLUS : 0;
}

// sorted in increasing order
int antiNeigs(const adjMatrix * g, int r, const int * R, int asz, int * ad, int * ang, int * surplus_p) {
	if (g) {
		setAdjMatrix(g);
	}

	int aa = 0, j;
	int i;
	*surplus_p = asz;
	for (i = 0; i < r; i++) {
		ad[i] = 0;
		for (j = 0; j < r; j++)
			if (i != j && !hasEdge(R[i], R[j])) {
				(*surplus_p)--;
				if (*surplus_p >= 0)
					ang[aa++] = j;
				ad[i]++;
			}
	}

	if (g && defaultg) {
		setAdjMatrix(defaultg);
	}

	return (*surplus_p < 0) ? GSTERR_NEGATIVE_SURPLUS : 0;
}

int antiNeigSize(adjMatrix * g, int r, int * R, int i, int * antideg) {
	if (g) {
		setAdjMatrix(g);
	}

	int j;
	(*antideg) = 0;
	for (j = 0; j < r; j++)
		if (i != j && !hasEdge(R[i], R[j]))
			(*antideg)++;

	if (g && defaultg) {
		setAdjMatrix(defaultg);
	}

	return 0;
}

int antiNeigSizes(adjMatrix * g, int r, int * R, int * antideg) {
	if (g) {
		setAdjMatrix(g);
	}

	memset(antideg, 0, r*sizeof(int));

	int iu, iv;
	for (iu = 0; iu < r; iu++) {
		for (iv = iu+1; iv < r; iv++)
			if (!hasEdge(R[iu], R[iv])) {
				antideg[iu]++;
				antideg[iv]++;
			}
	}

	if (g && defaultg) {
		setAdjMatrix(defaultg);
	}

	return 0;
}

// Anti-neighborhoods

int neig(adjMatrix * g, int r, int * R, int i, int asz, int * ng, int * surplus_p) {
	if (g) {
		setAdjMatrix(g);
	}

	int ia = 0, j;
	*surplus_p = asz;
	for (j = 0; j < r; j++)
		if (i != j && hasEdge(R[i], R[j])) {
			(*surplus_p)--;
			if (*surplus_p >= 0)
				ng[ia++] = j;
		}

	if (g && defaultg) {
		setAdjMatrix(defaultg);
	}

	return (*surplus_p < 0) ? GSTERR_NEGATIVE_SURPLUS : 0;
}

int neigs(adjMatrix * g, int r, int * R, int asz, int * ad, int * ang, int * surplus_p) {
	if (g) {
		setAdjMatrix(g);
	}

	int aa = 0, j;
	int i;
	*surplus_p = asz;
	for (i = 0; i < r; i++) {
		ad[i] = 0;
		for (j = 0; j < r; j++)
			if (i != j && hasEdge(R[i], R[j])) {
				(*surplus_p)--;
				if (*surplus_p >= 0)
					ang[aa++] = j;
				ad[i]++;
			}
	}

	if (g && defaultg) {
		setAdjMatrix(defaultg);
	}

	return (*surplus_p < 0) ? GSTERR_NEGATIVE_SURPLUS : 0;
}

int neigSize(adjMatrix * g, int r, int * R, int i, int * deg) {
	if (g) {
		setAdjMatrix(g);
	}

	int j;
	(*deg) = 0;
	for (j = 0; j < r; j++)
		if (hasEdge(R[i], R[j]))
			(*deg)++;

	if (g && defaultg) {
		setAdjMatrix(defaultg);
	}

	return 0;
}

int neigSizes(adjMatrix * g, int r, int * R, int * deg) {
	if (g) {
		setAdjMatrix(g);
	}

	memset(deg, 0, r*sizeof(int));

	int iu, iv;
	for (iu = 0; iu < r; iu++) {
		for (iv = iu+1; iv < r; iv++)
			if (hasEdge(R[iu], R[iv])) {
				deg[iu]++;
				deg[iv]++;
			}
	}

	if (g && defaultg) {
		setAdjMatrix(defaultg);
	}

	return 0;
}
